package hn.cch.redisson.service;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class ScheduleServiceImpl implements ScheduleService {

    private final static Logger logger = LoggerFactory.getLogger(ScheduleServiceImpl.class);


    @Autowired
    private RedissonClient redissonClient;

    public List<String> getReadyTasks() {
        List<String> taskList = new ArrayList<>();
        taskList.add("task-0");
        taskList.add("task-1");
        return taskList;
    }

    public void scheduleTask() {
        while (true) {
            try {
                logger.info("sleep 1min later get ready tasks");
                Thread.sleep(60 * 1000);
                List<String> readyTasks = getReadyTasks();
                if (CollectionUtils.isEmpty(readyTasks)) {
                    logger.info("get ready tasks is empty, wait next scan task");
                    continue;
                }
                logger.info("get ready {} tasks, do per task", readyTasks.size());
                for (String taskName : readyTasks) {
                    RLock rLock = redissonClient.getLock(taskName);
                    boolean lockFlag = false;
                    try {
                        lockFlag = rLock.tryLock(10, TimeUnit.SECONDS);
                        if (lockFlag) {
                            logger.info("start {} get lock success", taskName);
                            // 业务代码执行
                            this.run(taskName);
                        } else {
                            logger.info("start {} get lock failed", taskName);
                        }
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    } finally {
                        if (lockFlag) {
                            rLock.unlock();
                            logger.info("{} do complete and unlock", taskName);
                        }
                    }
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }


    public void run(String taskName) throws InterruptedException {
        Random random = new Random();
        long delay = (long) (random.nextFloat() * 60 * 1000);
        logger.info("{} sleep {} millis start", taskName, delay);
        Thread.sleep(delay);
        logger.info("{} sleep {} millis end", taskName, delay);
    }

}
